/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.gidoo.cms.admin;

import org.gidoo.cms.RedirectPage;
import org.gidoo.cms.admin.addins.AddInPanel;
import org.gidoo.cms.admin.addins.SectionsPanel;
import org.gidoo.cms.admin.addins.SingleSectionPanel;
import org.gidoo.cms.admin.addins.SingleUserPanel;
import org.gidoo.cms.admin.addins.UsersPanel;
import org.gidoo.cms.data.CMSSection;
import org.gidoo.cms.data.RegisteredUser;
import org.gidoo.cms.dbconnection.Persistance;
import org.gidoo.cms.login.GidooCMSAuthenticatedWebSession;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.authorization.strategies.role.Roles;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.markup.html.tree.ITreeStateListener;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.gidoo.cms.GidooCMS;
import org.gidoo.cms.data.CMSSection;
import org.gidoo.cms.data.RegisteredUser;

@AuthorizeInstantiation(Roles.ADMIN)
/**
 * This page is the container for all administrative actions.
 * @author Thomas
 */
public class AdminPage extends WebPage implements ITreeStateListener
{

  public static final ResourceReference CSS_ADMIN = 
    new ResourceReference(AdminPage.class, "admin.css");
  
  private BaseTree treeNav;
  private DefaultTreeModel treeNavModel;
  private AddInPanel panelAddIn;
  private DefaultMutableTreeNode rootNode;
  private DefaultMutableTreeNode userNode;
  private DefaultMutableTreeNode sectionNode;
  private DefaultMutableTreeNode selectedNode;

  /** Creates a new instance of AdminPage */
  public AdminPage()
  {
    add(HeaderContributor.forCss(CSS_ADMIN));
    
    add(new Label("lblTitle", new ResourceModel("administration")));

    createTree();

    panelAddIn = new AddInPanel("panelAddIn");
    add(panelAddIn);

    add(new Link("lnkLogout")
    {

      public void onClick()
      {
        ((GidooCMSAuthenticatedWebSession) this.getSession()).signOut();
        this.setResponsePage(RedirectPage.class);
      }
    });

  }

  private void createTree()
  {
    rootNode = new DefaultMutableTreeNode("root");

    userNode = new DefaultMutableTreeNode(getString("user"));
    sectionNode = new DefaultMutableTreeNode(getString("section"));

    rootNode.add(userNode);
    rootNode.add(sectionNode);

    treeNavModel = new DefaultTreeModel(rootNode);

    treeNav = new BaseTree("treeNav", new Model(treeNavModel))
    {

      protected Component newNodeComponent(String id, IModel model)
      {
        return new TreePanel(id, model, treeNav, userNode, sectionNode);
      }
    };
    treeNav.setRootLess(true);
    treeNav.getTreeState().collapseAll();
    treeNav.getTreeState().setAllowSelectMultiple(false);
    treeNav.getTreeState().addTreeStateListener(this);

    updateTreeModel(null, null);

    add(treeNav);
  }

  public void updateDataAndView()
  {
    reloadAddin();

    if (selectedNode != null)
    {
      if (selectedNode == userNode)
      {
        updateTreeModel(null, null);
        treeNav.getTreeState().selectNode(selectedNode, true);
      }
      else if (selectedNode == sectionNode)
      {
        updateTreeModel(null, null);
        treeNav.getTreeState().selectNode(sectionNode, true);
      }
      else if (selectedNode.getUserObject() instanceof CMSSection)
      {
        updateTreeModel(null, (CMSSection) selectedNode.getUserObject());
      }
      else if (selectedNode.getUserObject() instanceof RegisteredUser)
      {
        updateTreeModel((RegisteredUser) selectedNode.getUserObject(), null);
      }
    }
    else
    {
      updateTreeModel(null, null);
    }
  }

  /** Updates the model (all changeable items) of the navigation tree. */
  public void updateTreeModel(RegisteredUser userToSelect, CMSSection sectionToSelect)
  {

    userNode.removeAllChildren();
    sectionNode.removeAllChildren();

    try
    {
      List<RegisteredUser> users = 
        ((GidooCMS) getApplication()).getDb().getAllUsers();

      for (RegisteredUser u : users)
      {
        DefaultMutableTreeNode cur = new DefaultMutableTreeNode(u);
        userNode.add(cur);
        if (u.equals(userToSelect))
        {
          treeNav.getTreeState().selectNode(cur, true);
        }
      }

    }
    catch (Exception ex)
    {
      Logger.getLogger(AdminPage.class.getName()).log(Level.SEVERE, null, ex);
      error(ex.toString());
    }

    try
    {
      List<CMSSection> sections = ((GidooCMS) getApplication()).getDb().getAllSections();

      for (CMSSection s : sections)
      {
        DefaultMutableTreeNode cur = new DefaultMutableTreeNode(s);
        sectionNode.add(cur);
        if (s.equals(sectionToSelect))
        {
          treeNav.getTreeState().selectNode(cur, true);
        }
      }

    }
    catch (Exception ex)
    {
      Logger.getLogger(AdminPage.class.getName()).log(Level.SEVERE, null, ex);
      error(ex.toString());
    }

    if (treeNavModel != null)
    {
      treeNavModel.reload();
    }

  }

  private void reloadAddin()
  {
    if (selectedNode == null)
    {
      panelAddIn = new AddInPanel("panelAddIn");
      replace(panelAddIn);
    }
    else if (selectedNode == userNode)
    {
      panelAddIn = new UsersPanel("panelAddIn", this);
      replace(panelAddIn);
    }
    else if (selectedNode == sectionNode)
    {
      panelAddIn = new SectionsPanel("panelAddIn", this);
      replace(panelAddIn);
    }
    else if (selectedNode.getUserObject() instanceof RegisteredUser)
    {
      panelAddIn = new SingleUserPanel("panelAddIn",
        (RegisteredUser) selectedNode.getUserObject(), this);
      replace(panelAddIn);
    }
    else if (selectedNode.getUserObject() instanceof CMSSection)
    {
      panelAddIn =
        new SingleSectionPanel("panelAddIn",
        (CMSSection) selectedNode.getUserObject(), this);
      replace(panelAddIn);
    }
    else
    {
      panelAddIn = new AddInPanel("panelAddIn");
      replace(panelAddIn);
      error(getString("novalidselection"));
    }
  }

  public DefaultMutableTreeNode getSelectedNode()
  {
    return selectedNode;
  }

  public void setSelectedNode(DefaultMutableTreeNode selectedNode)
  {
    this.selectedNode = selectedNode;
  }

  public BaseTree getTreeNav()
  {
    return treeNav;
  }

  
  
  /* ITreeStateListener functions */
  public void allNodesCollapsed()
  {
  }

  public void allNodesExpanded()
  {
  }

  public void nodeCollapsed(TreeNode node)
  {
  }

  public void nodeExpanded(TreeNode node)
  {
  }

  public void nodeSelected(TreeNode node)
  {
    selectedNode = (DefaultMutableTreeNode) node;
    reloadAddin();
    setResponsePage(this);

  }

  public void nodeUnselected(TreeNode node)
  {
    selectedNode = null;
    reloadAddin();
    setResponsePage(this);
  }
}
